#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* 
*   @author Joseph Conrad Stack
*           jcstack
*           memMgr.c
*   
*   this program provides methods to manipulate a bitmap 
*   of 256 bits. 
*
*/

/*
*   initialize functions
*/
void initMem();
int getMem();
void freeMem(int position);
void displayMap();
int power(int base, int n);


/*
*   initialize global variables
 *  @param bmap     is an array of ints with bits totaling 256
 *  @param tryand   is the number 1 used to determine a bits state
*/
unsigned int bmap[8] = {0,0,0,0,0,0,0,0};
int tryand = 0x00000001;


/*
*   initMem method initializes all bits to 0
 *  @param i    used to parse through the int array
 */ 
void initMem(){
    int i =0;
    for(i=0; i<8; i++){
        bmap[i] = 0x00000000;
    }
}
 

/*
*   getMem method parses the bitmap until it finds and open 
 *  space,sets it to 1, and returns its position
 *  @param p        holds the position of the free space
 *  @param i        used to parse through bits
 *  @param j        used to parse through bits
 *	@param x        holds the number of rows parsed 
 *  @param temp     used to hold the current row that is being parsed
 *  @param tryzero  is the number zero, used to determine is space is free
 *  @param hold     holds a temp bit row with just the open position bit set to 1
 *  
 *  @return         returns the position is there is one available, -1 otherwise
 */
int getMem(){
    int p=0;
    int i = 0;
    int j = 0;
    int x = 0;
    unsigned int temp;
    int tryzero = 0x00000000;
    int hold =0;
	
    for(i=0;i<8;i++){
        temp = bmap[i];
        p=0;
        for(j=0;j<32;j++){
            if((temp & tryand) == tryzero){
                hold = power(2,p);
                bmap[i] = bmap[i] | hold;                
                return (x*32) + p;
            }
            else{
                temp >>= 1;
                p++;
            }
        }
        x++;
    }
    if(p > 30){
        return -1;
    }

    return -1;
}


/*
*   freeMem method takes in an int and finds that position in the bit map
 *  after which it sets that bit to 0.
 *  @param p        holds the row number of the bit map
 *  @param m        holds the column number of the bit map
 *  @param temp     contains a row in which only the position(int) is set
 *  @param position is the position to be cleared
 */ 
void freeMem(int position){

    int p=0;
    int m=0;
    unsigned int temp;

    if((position < 0) || (position > 255)){
        printf("value %d must be within 0-255 range\n",position);
    }
    else if (position == 0) {
        bmap[0] >>= 1;
        bmap[0] <<= 1;
    }
    else{
        p=(position/32);
        m=(position%32);
        temp = power(2,m);
        temp = temp ^ 0xffffffff;
        bmap[p] = (bmap[p] & temp);
    }
}

/* 
*   displayMap prints out the bitmap in hex
 *  @param i    used to parse through the bitmap
 */
void displayMap(){
    int i=0;
    for (i=0;i<8;i++) {
        printf("\n%0.8x",bmap[i]);
    }
    printf("\n");
}
    


/*
*   power method makes it possible to use exponentials with ints
 *  @author csc451(sec 001) instructor or TA
 * 
 *  this method was taken off of power.c under course page>resources>sample code>power.c
 */ 

int power (int base, int n) {
        int i;
        int p;
        p = 1;
        for (i = 1; i <= n; i++) {
            p = p * base;
        }
        return p;
}

